package com.cqc.jdk8.Jutil.concurrent;

import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class CountDownLatchTest {

    /**
     * 串行执行任务
     * CountDownLatch.await() 会阻塞调用它的线程（无论是主线程还是子线程）。
     * 若主线程需要等待子线程完成任务，可以使用 CountDownLatch，但需确保计数器最终归零。
     */
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        CountDownLatch latch = new CountDownLatch(3);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("###任务1  " + DateFormat.getDateTimeInstance().format(new Date()));
                latch.countDown();
            }
        });
        executorService.execute(() -> {
            System.out.println("###任务2  " + DateFormat.getDateTimeInstance().format(new Date()));
            latch.countDown();
        });
        executorService.execute(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
            System.out.println("###任务3  " + DateFormat.getDateTimeInstance().format(new Date()));
            latch.countDown();
        });
        try {
            // 一定记得加上timeout时间，防止阻塞主线程（也就是说，主线程最多等2s）
            latch.await(2, TimeUnit.SECONDS);
//            latch.await();
            //3个任务都走完了，才会走await()后的代码
            System.out.println("###latch.await()后" + DateFormat.getDateTimeInstance().format(new Date()));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //5.关闭线程池
        executorService.shutdown();
    }
}
